#include "cn_tcpclient.h"
#include "command_process.h"
#include "cn_fifo.h"
//int tcp_server_port = 8001; //服务器端口
//const u8 tcp_server_ip[] = "172.20.10.11";//服务器IP

int tcp_client_port = 7001; //客户端端口
const u8 tcp_client_ip[] = "192.168.1.2";//客户端IP
#define     DEMO_SOCK_C_TASK_SIZE      		1024
#define     DEMO_SOCK_BUF_SIZE            	1024

static OS_STK   socket_process_task_stk[DEMO_SOCK_C_TASK_SIZE];
static OS_STK   socket_rcv_task_stk[DEMO_SOCK_C_TASK_SIZE];

typedef struct demo_sockc_uart
{
	u8 *rxbuf;
	u16 rxlen;
}ST_Demo_Sockc_uart;

ST_Demo_Sock_Client *cn_sock_client =NULL;

tls_os_queue_t *demo_sockc_q = NULL;

ST_Demo_Sockc_uart demo_sockc_uart = {0}; 

static void socket_client_process_task(void *sdata);
static void socket_client_recv_task(void *sdata);
static void socket_net_status_changed_event(u8 status );
static int create_client_socket(void);
static int socket_client_show(void);

//客户端连上指定wifi后立马新建客户端
int Socket_Client_Create(u32 ip_addr,int port)
{
    if (cn_sock_client)
    {
        printf("run\n");
        return WM_FAILED;
    }
 //   printf("\nremote ip: %s, remote port: %d\n",tcp_server_ip, tcp_server_port);

    if (NULL == cn_sock_client)
    {
        cn_sock_client = tls_mem_alloc(sizeof(ST_Demo_Sock_Client));
        if (NULL == cn_sock_client)
        {
            goto _error;
        }
        memset(cn_sock_client, 0, sizeof(ST_Demo_Sock_Client));

        cn_sock_client->sock_rx = tls_mem_alloc(DEMO_SOCK_BUF_SIZE + 1);
        if (NULL == cn_sock_client->sock_rx)
        {
            goto _error3;
        }

        cn_sock_client->sock_tx = tls_mem_alloc(DEMO_SOCK_BUF_SIZE + 1);
        if (NULL == cn_sock_client->sock_tx)
        {
            goto _error4;
        }

        tls_os_queue_create(&(cn_sock_client->sock_c_q),DEMO_QUEUE_SIZE);
        tls_os_queue_create(&demo_sockc_q, DEMO_QUEUE_SIZE);
        //用户处理socket相关的消息
        tls_os_task_create(NULL, NULL,
                            socket_client_process_task,
                            (void *)cn_sock_client,
                            (void *)socket_process_task_stk,        /* 任务栈的起始地址 */
                            DEMO_SOCK_C_TASK_SIZE,  /* 任务栈的大小     */
                            DEMO_SOCKET_C_TASK_PRIO,
                            0);
        //用于socket数据的接收
        tls_os_task_create(NULL, NULL,
                            socket_client_recv_task,
                            (void *)cn_sock_client,
                            (void *)socket_rcv_task_stk,        /* 任务栈的起始地址 */
                            DEMO_SOCK_C_TASK_SIZE,  /* 任务栈的大小     */
                            DEMO_SOCKET_RECEIVE_TASK_PRIO,
                            0);
    }
    cn_sock_client->remote_port = port;
//    cn_sock_client->remote_ip = ipaddr_addr((char *)tcp_server_ip);
    cn_sock_client->remote_ip = ip_addr;
    return WM_SUCCESS;

_error4:
    tls_mem_free(cn_sock_client->sock_rx);
_error3:
    tls_mem_free(cn_sock_client);
    cn_sock_client = NULL;
_error:
    return WM_FAILED;
}

int send_tcpclient(uint8_t *data,uint32_t len)
{
    uint32_t readlen = len;
    uint32_t ret = 0,offset = 0; 
    if (cn_sock_client->socket_ok)
    {
        do{
            ret = send(cn_sock_client->socket_num, data, readlen, 0);
            offset += ret;
            readlen -= ret;
        }while(readlen);
    }
    return 0; 
}

static void socket_net_status_changed_event(u8 status )
{
    printf("[tcp]udp_net_status_changed_event:%d",status);
	switch(status)
	{
		case NETIF_WIFI_JOIN_FAILED:
			printf("NETIF_WIFI_JOIN_FAILED\n");
			tls_os_queue_send(cn_sock_client->sock_c_q, (void *)DEMO_MSG_WJOIN_FAILD, 0);
			break;
		case NETIF_WIFI_JOIN_SUCCESS:
			printf("NETIF_WIFI_JOIN_SUCCESS\n");
			tls_os_queue_send(cn_sock_client->sock_c_q, (void *)DEMO_MSG_WJOIN_SUCCESS, 0);
			break;
		case NETIF_IP_NET_UP:
			printf("NETIF_IP_NET_UP\n");
			tls_os_queue_send(cn_sock_client->sock_c_q, (void *)DEMO_MSG_SOCKET_CREATE, 0);
			break;
		default:
			break;
	}
}

static void socket_client_process_task(void *sdata)
{
    ST_Demo_Sock_Client *sock_c = (ST_Demo_Sock_Client *)sdata;
    void *msg;
    struct tls_ethif * ethif = tls_netif_get_ethif();
    int len;
    int ret;
	void *uart_msg;
	u16 offset = 0;
	u16 readlen = 0;


    printf("\nsocket_client_process_taskk\n");
    tls_netif_add_status_event(socket_net_status_changed_event);

    for (;;)
    {
        tls_os_queue_receive(sock_c->sock_c_q, (void **)&msg, 0, 0);
	//printf("\n msg =%d\n",msg);
        switch((u32)msg)
        {
            case DEMO_MSG_WJOIN_SUCCESS:
                break;

            case DEMO_MSG_SOCKET_CREATE:
                socket_client_show();
                break;

            case DEMO_MSG_WJOIN_FAILD:
                if(sock_c->socket_num > 0)
                {
                    sock_c->socket_num = 0;
                    sock_c->socket_ok = FALSE;
                }
                break;

            case DEMO_MSG_SOCKET_ERR:
                tls_os_time_delay(500);
 //               printf("\nsocket err\n");
                create_client_socket( );
                break;

            default:
                break;
        }
    }

}

static void socket_client_recv_task(void *sdata)
{
    ST_Demo_Sock_Client *sock_c = (ST_Demo_Sock_Client *)sdata;
    int ret = 0;
	u16 offset = 0;
	u16 readlen = 0;
	
    for(;;)
    {
        if (sock_c->socket_ok)
        {
            ret = 0;
            ret = recv(sock_c->socket_num, sock_c->sock_rx, DEMO_SOCK_BUF_SIZE, 0);
            if(ret>0)
            {
                sock_c->rcv_data_len += ret;
                printf("[tcp] len=%d\n",  ret);
#if 0
                readlen = ret;
                offset = 0;
                do{
                    ret = send(sock_c->socket_num, sock_c->sock_rx + offset, readlen, 0);
                    offset += ret;
                    readlen -= ret;
                }while(readlen);
#else
                fifo_puts(&rcv_wlan_fifo, sock_c->sock_rx,ret);
#endif        			
            }
            else
            {
                sock_c->socket_ok = FALSE;
                closesocket(sock_c->socket_num);
                printf("closesocket: %d\n", sock_c->socket_num);
                sock_c->socket_num = 0;
                tls_os_queue_send(sock_c->sock_c_q, (void *)DEMO_MSG_SOCKET_ERR, 0);
            }
            continue;
        }
        tls_os_time_delay(1);
    }
}

static int create_client_socket(void)
{
    struct sockaddr_in pin;
		struct sockaddr_in client_addr;
	  struct tls_ethif * ethif;
    ethif = tls_netif_get_ethif();
#if 0
		u8 send_buf[] = "WIFITESTWIFITESTWIFITESTWIFITESTWIFITEST";//连接成功后立马发送数据
		u16 offset = 0;
		u16 readlen = 0;
		int ret = 0;
#endif
	  cn_sock_client->socket_num = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	//增加客户端指定端口
	  memset(&client_addr, 0, sizeof(struct sockaddr));
    client_addr.sin_family = AF_INET;   
    client_addr.sin_port = htons(7001); 
	client_addr.sin_addr.s_addr = ethif->ip_addr.addr; 
    memset(client_addr.sin_zero, '\0', sizeof(client_addr.sin_zero));
    if (bind(cn_sock_client->socket_num, (struct sockaddr *) &client_addr,
         sizeof(client_addr)) == -1)
    {
        closesocket(cn_sock_client->socket_num);
        tls_os_queue_send(cn_sock_client->sock_c_q, (void *)DEMO_MSG_SOCKET_ERR, 0);
        printf("bind err\n");
        return 1;
    }
		
    memset(&pin, 0, sizeof(struct sockaddr));
    pin.sin_family=AF_INET;                 //AF_INET表示使用IPv4
    pin.sin_addr.s_addr = cn_sock_client->remote_ip;
    pin.sin_port=htons(cn_sock_client->remote_port);

//    printf("\nsocket num=%d\n",cn_sock_client->socket_num);
    if (connect(cn_sock_client->socket_num, (struct sockaddr *)&pin, sizeof(struct sockaddr)) != 0)
    {
        printf("connect failed! socket num=%d\n", cn_sock_client->socket_num);
        closesocket(cn_sock_client->socket_num);
        tls_os_queue_send(cn_sock_client->sock_c_q, (void *)DEMO_MSG_SOCKET_ERR, 0);
        return WM_FAILED;
    }
    else
    {
		printf("connect succes! socket num=%d\n", cn_sock_client->socket_num);
        cn_sock_client->socket_ok = TRUE;
#if 0
				offset = 0;
				readlen = strlen((const char *)send_buf);
				do{
					ret = send(cn_sock_client->socket_num, send_buf + offset, readlen, 0);
					offset += ret;
					readlen -= ret;
				}while(readlen);
#endif
    }

    return WM_SUCCESS;
}

static int socket_client_show(void)
{
    struct tls_ethif * ethif;

    ethif = tls_netif_get_ethif();
#if TLS_CONFIG_LWIP_VER2_0_3
    printf("\nclient local ip=%d.%d.%d.%d,\n",  ip4_addr1(ip_2_ip4(&ethif->ip_addr)),ip4_addr2(ip_2_ip4(&ethif->ip_addr)),

		ip4_addr3(ip_2_ip4(&ethif->ip_addr)),ip4_addr4(ip_2_ip4(&ethif->ip_addr)));
#else
  printf("\nip client =%d.%d.%d.%d\n", ip4_addr1(ip_2_ip4(&ethif->ip_addr)), ip4_addr2(ip_2_ip4(&ethif->ip_addr)),

        ip4_addr3(ip_2_ip4(&ethif->ip_addr)), ip4_addr4(ip_2_ip4(&ethif->ip_addr)));
#endif
    if(ethif->status)	//已经在网
    {
		printf("\nclient local nethif->status = %d,Succes!!\n",ethif->status);
    }
    else
    {
        printf("\nclient local nethif->status = %d,Fail!!\n",ethif->status);
    }
    //DemoStdSockOneshotSendMac();

    return create_client_socket();
}

